/*******************************************************************************
* Copyright (C) 2019 China Micro Semiconductor Limited Company. All Rights Reserved.
*
* This software is owned and published by:
* CMS LLC, No 2609-10, Taurus Plaza, TaoyuanRoad, NanshanDistrict, Shenzhen, China.
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with CMS
* components. This software is licensed by CMS to be adapted only
* for use in systems utilizing CMS components. CMS shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. CMS is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/

/****************************************************************************/
/** \file app_crc.c
**
**	History:
**	
*****************************************************************************/
/****************************************************************************/
/*	include files
*****************************************************************************/
#include "main.h"
/****************************************************************************/
/*	Local pre-processor symbols/macros('#define')
*****************************************************************************/

/****************************************************************************/
/*	Global variable definitions(declared in header file with 'extern')
*****************************************************************************/

/****************************************************************************/
/*	Local type definitions('typedef')
*****************************************************************************/

/****************************************************************************/
/*	Local variable  definitions('static')
*****************************************************************************/

/****************************************************************************/
/*	Local function prototypes('static')
*****************************************************************************/

/****************************************************************************/
/*	Function implementation - global ('extern') and local('static')
*****************************************************************************/
#include "main.h"

/**/
SEN_STR strInput;

/*Functions*/

/***********************************************************************************************************************
* Function Name:
* Description  : 
* Arguments    : 
* Return Value : 
***********************************************************************************************************************/
void UI_Init_Variables(void)
{	
	strInput.sensorFlag.Word = 0;
	strInput.ErrorFlag.Word = 0;
	strInput.StaVoltmV = VOLT_STA_MV;
	strInput.SuvpTimeMs = TIME_SUVP_MS;
	
	strInput.OverVoltmV = VOLT_OVP_MV;
	strInput.OvpTimeMs = TIME_OVP_MS;
	
	strInput.UnderVolt1mV = VOLT_UVP1_MV;
	strInput.Uvp1TimeMs = TIME_UVP1_MS;

	strInput.UnderVolt2mV = VOLT_UVP2_MV;
	strInput.Uvp2TimeMs = TIME_UVP2_MS;	
	
	strInput.OtpAdc1P = OTP_ADC1_P;
	strInput.OtpTime1Ms = TIME_OTP1_MS;
	strInput.OtpAdc1R = OTP_ADC1_R;

	strInput.OtpAdc2P = OTP_ADC2_P;
	strInput.OtpTime2Ms = TIME_OTP2_MS;
	strInput.OtpAdc2R = OTP_ADC2_R;
	
	strInput.LowSpeedRpm = LOW_SPEED_RPM;
	strInput.LsptimeMs = TIME_LSP_MS;
	
	strInput.OcpmA1 = CURT_OCP1_MA;
	strInput.OcpmA2 = CURT_OCP2_MA;
	strInput.OcpmA3 = CURT_OCP3_MA;
	strInput.OcpmA4 = CURT_OCP4_MA;
	strInput.OppmA1 = CURT_OPP1_MA;
	
	strInput.OcpADC1 = Calculate_Ibus_ADC(CURT_OCP1_MA / 1000) ;
	strInput.OcpADC2 = Calculate_Ibus_ADC(CURT_OCP2_MA / 1000) ;
	strInput.OcpADC3 = Calculate_Ibus_ADC(CURT_OCP3_MA / 1000) ;
	strInput.OcpADC4 = Calculate_Ibus_ADC(CURT_OCP4_MA / 1000) ;
	
	strInput.OcpTimeMs1 = TIME_OCP1_MS;
	strInput.OcpTimeMs2 = TIME_OCP2_MS;
	strInput.OcpTimeMs3 = TIME_OCP3_MS;
	strInput.OcpTimeMs4 = TIME_OCP4_MS;
	strInput.OppTimeMs1 = TIME_OPP1_MS;
	
	strInput.sensorFlag.bits.gDirStatus = DIR_CCW;

		
	
	
	
}
/***********************************************************************************************************************
* Function Name:
* Description  : 
* Arguments    : 
* Return Value : 
***********************************************************************************************************************/
void UI_Get_Key_Status(void)
{
	//static uint8_t cntPowerKeyOn = 0;
	//static uint8_t cntPowerKeyOff = 0; 

	//static uint8_t cntStartKeyOn = 0;
	//static uint8_t cntStartKeyOff = 0;
	//static uint8_t cntStartKeyRepeat = 0;
	//static uint8_t cntReset = 0;
	//static uint16_t cntHoldKeyOn = 0;
	static uint8_t cntDirSwOn = 0;
	static uint8_t cntDirSwOff = 0;
	static uint8_t cntSpnKeyOn = 0;
	static uint8_t cntSpnKeyOff = 0;
		
/*START KEY*/	

#if(0)
	if(START_KEY_ON)
	{
		if(strInput.sensorFlag.bits.gPowerKeyStatus == 0)
		{
			if(++cntPowerKeyOn >= 25)
			{
				cntPowerKeyOn = 0;
				strInput.sensorFlag.bits.gPowerKeyStatus = 1;		
				strUctr.CtrFlag.bits.gSOCdisplay = 1;
			}
		}
		else
		{
			cntPowerKeyOn = 0;
		}	

		if(++cntHoldKeyOn >= 2000)
		{
			strInput.sensorFlag.bits.gPowerKeyHoldOn = 1;
		}
	}	
	else
	{
		cntPowerKeyOn = 0;
		cntHoldKeyOn = 0;
		strInput.sensorFlag.bits.gPowerKeyHoldOn = 0;  //cutter use , hold 3s power off
	}

	if(START_KEY_OFF)
	{
		if(strInput.sensorFlag.bits.gPowerKeyStatus == 1)
		{
			if(++cntPowerKeyOff  >= 25)
			{
				cntPowerKeyOff = 0;
				strInput.sensorFlag.bits.gPowerKeyStatus = 0;					
			}
		}
		else
		{
			cntPowerKeyOff = 0;
		}		
	}
	else
	{
		cntPowerKeyOff = 0;
	}
#endif

/*START KEY*/	

/*DRILL DIR SW*/

	if(DIR_SW_CW)
	{
		if(strInput.sensorFlag.bits.gDirStatus == 1)
		{
			if(++cntDirSwOn  >= 25)
			{
				cntDirSwOn = 0;
				strInput.sensorFlag.bits.gDirStatus = 0;					
			}
		}
		else
		{
			cntDirSwOn = 0;
		}		
	}
	else
	{
		cntDirSwOn = 0;
	}		

	if(DIR_SW_CCW)
	{
		if(strInput.sensorFlag.bits.gDirStatus == 0)
		{
			if(++cntDirSwOff >= 25)
			{
				cntDirSwOff = 0;
				strInput.sensorFlag.bits.gDirStatus = 1;
			}
		}
		else
		{
			cntDirSwOff = 0;
		}		
	}	
	else
	{
		cntDirSwOff = 0;
	}


/*DRILL DIR SW*/

/*Spanner Logic Key*/
#if(1)

	if(SPN_KEY_ON)
	{
		if(strInput.sensorFlag.bits.gSpnKeyStatus == 0)
		{
			if(++cntSpnKeyOn  >= 25)
			{
				cntSpnKeyOn = 0;
				
				if(strInput.sensorFlag.bits.gTriggerStatus == 0)
				{
					strInput.sensorFlag.bits.gSpnKeyStatus = 1;		
				}
			}
		}
		else
		{
			cntSpnKeyOn = 0;
		}		
	}
	else
	{
		cntSpnKeyOn = 0;
	}		

	if(SPN_KEY_OFF)
	{
		if(strInput.sensorFlag.bits.gSpnKeyStatus == 1)
		{
			if(++cntSpnKeyOff >= 25)
			{
				cntSpnKeyOff = 0;
				strInput.sensorFlag.bits.gSpnKeyStatus = 0;
			}
		}
		else
		{
			cntSpnKeyOff = 0;
		}		
	}	
	else
	{
		cntSpnKeyOff = 0;
	}

	
#endif

/*Spanner Logic Key*/


/*CUTTER USE*/	
#if(0)
	if(strInput.sensorFlag.bits.gTrgStatus == HALL_OFF)
	{
		if(strInput.sensorFlag.bits.gTriggerStatus == TRIGGER_OPEN)
		{
			if(++cntStartKeyOn >= 20)
			{
				cntStartKeyOn = 0;
				strInput.sensorFlag.bits.gTriggerStatus = TRIGGER_CLOSE;				
				cntReset = 0;				
			}
		}
		else
		{
			cntStartKeyOn = 0;
		}	
	}	
	else
	{
		cntStartKeyOn = 0;
	}
			
	
	if(strInput.sensorFlag.bits.gTrgStatus == HALL_ON) 
	{
		if(strInput.sensorFlag.bits.gTriggerStatus == TRIGGER_CLOSE)
		{
			if(++cntStartKeyOff  >= 20)
			{
				cntStartKeyOff = 0;
				strInput.sensorFlag.bits.gTriggerStatus = TRIGGER_OPEN;	
				if(++cntStartKeyRepeat >= 2)
				{			
					strInput.sensorFlag.bits.gTriggerRepeatDeal = 1;
				}
			}
		}
		else
		{
			cntStartKeyOff = 0;
		}		
	}
	else
	{
		cntStartKeyOff = 0;
	}
		
    if(cntStartKeyRepeat)
    {
        if(++cntReset >= 200) //250 * 2ms
        {
            cntStartKeyRepeat = 0;
            cntReset = 0;
        }
    }
    else
    {
        cntReset = 0;
    }
  #endif
/*CUTTER USE*/			
}
/***********************************************************************************************************************
* Function Name:
* Description  : 
* Arguments    : 
* Return Value : 
***********************************************************************************************************************/
void UI_Get_Trigger_Status(void)
{
	static uint8_t cntTriggerOn = 0;
	static uint8_t cntTriggerOff = 0;
	//static uint8_t cntSpeed1 = 0;
	//static uint8_t cntSpeed2 = 0;
	//static uint8_t cntSpeed3 = 0;

	strInput.triggerAdc = ADC1_GetResult(RESULT_VSP);	
	//strInput.triggerAdc = 4096 - strInput.triggerAdc;   
	//strInput.triggerAdc =(uint16_t) 700;   //for test 

	if(strInput.triggerAdc >1000)
	{
		//strInput.triggerAdc=2048;
		if(strInput.sensorFlag.bits.gTriggerStatus == 0)
		{
			if(++cntTriggerOn >= 25)
			{
				cntTriggerOn = 0;
				strInput.sensorFlag.bits.gTriggerStatus = 1;				
			}
		}
		else
		{
			cntTriggerOn = 0;
		}	
	}	
	else
	{
		cntTriggerOn = 0;
		strInput.sensorFlag.bits.gTriggerStatus=0;
		strUctr.ErrorFlag.Word = strInput.ErrorFlag.Word=0;
		strUctr.ErrorFlag.Word = strMpro.ErrorFlag.Word=0;
		strUctr.WriteErrorFlag.Word = strUctr.ErrorFlag.Word=0;
	}
	
	/*TRIGGER */
//	if(strInput.triggerAdc > TRG_ON_ADC)
//	{
//		if(strInput.sensorFlag.bits.gTriggerStatus == 0)
//		{
//			if(++cntTriggerOn >= 25)
//			{
//				cntTriggerOn = 0;
//				strInput.sensorFlag.bits.gTriggerStatus = 1;				
//			}
//		}
//		else
//		{
//			cntTriggerOn = 0;
//		}	
//	}	
//	else
//	{
//		cntTriggerOn = 0;
//	}

//	if(strInput.triggerAdc <  (TRG_ON_ADC - 200))
//	{
//		if(strInput.sensorFlag.bits.gTriggerStatus == 1)
//		{
//			if(++cntTriggerOff >= 25)
//			{
//				cntTriggerOff = 0;
//				strInput.sensorFlag.bits.gTriggerStatus = 0;					
//			}
//		}
//		else
//		{
//			cntTriggerOff = 0;
//		}		
//	}
//	else
//	{
//		cntTriggerOff = 0;
//	}

#if(0)	
	if((strInput.triggerAdc > (619 - 200)) &&(strInput.triggerAdc < (619 + 200)))
	{
		if(++cntSpeed1 >= 10)
		{
			strInput.speedLevel = 1;
			cntSpeed1 = 0;
		}
	}
	else 
	{
		cntSpeed1 = 0;
	}
	
	if((strInput.triggerAdc > (975 - 200)) &&(strInput.triggerAdc < (975 + 200)))
	{
		if(++cntSpeed2 >= 10)
		{
			strInput.speedLevel = 2;
			cntSpeed2= 0;
		}
	}
	else 
	{
		cntSpeed2 = 0;
	}
	
	//if((strInput.triggerAdc > (2061 - 200)) &&(strInput.triggerAdc < (2061 + 200)))
	if(strInput.triggerAdc > (2061 - 200))
	{
		if(++cntSpeed3 >= 10)
		{
			strInput.speedLevel = 3;
			cntSpeed3 = 0;
		}
	}
	else 
	{
		cntSpeed3 = 0;
	}

#endif	
}
/***********************************************************************************************************************
* Function Name:
* Description  : 
* Arguments    : 
* Return Value : 
***********************************************************************************************************************/
void UI_Get_Bus_Volt(void)
{
	static uint16_t msCntOvp = 0;
	static uint16_t msCntUvp1 = 0;
	static uint16_t msCntUvp2 = 0;
	uint16_t cmp_volt_mv;
	uint16_t cmp_cnt_ms;
    
	if(strUctr.CtrFlag.bits.gFirstStart)
	{
		cmp_volt_mv = strInput.StaVoltmV;
		cmp_cnt_ms = strInput.SuvpTimeMs;
	}
	else
	{
		cmp_volt_mv = strInput.UnderVolt1mV;
		cmp_cnt_ms = strInput.Uvp1TimeMs;
	}
	
	strInput.batteryVoltageADC = ADC1_GetResult(RESULT_VBUS);	
	strInput.batteryVoltagemV = Calculate_ADC_Vbus(strInput.batteryVoltageADC);
	
/*UVP1*/
	if(strInput.batteryVoltagemV < cmp_volt_mv)
	{	
		
		if(!strInput.ErrorFlag.bits.gLowVolt1)
		{
			if (++msCntUvp1 >= cmp_cnt_ms)
			{
				strInput.ErrorFlag.bits.gLowVolt1 = 1;
			}
		}
	}
	else
	{
		if(msCntUvp1 > 0)
		{
			msCntUvp1 --;
		}
		else
		{	
			strInput.ErrorFlag.bits.gLowVolt1 = 0;	
		}	
	}
	
/*UVP2*/

	if(strInput.batteryVoltagemV < strInput.UnderVolt2mV)
	{			
		if(!strInput.ErrorFlag.bits.gLowVolt2)
		{
			if (++msCntUvp2 >= strInput.Uvp2TimeMs)
			{
				strInput.ErrorFlag.bits.gLowVolt2 = 1;
			}
		}
	}
	else
	{
		if (msCntUvp2 > 0 )
		{
			msCntUvp2--;
		}
		else
		{
			strInput.ErrorFlag.bits.gLowVolt2 = 0;
		}
	}
/*OVP*/
#if(OVP_EN)
	if(strInput.batteryVoltagemV  >  strInput.OverVoltmV)
	{
		if(!strInput.ErrorFlag.bits.gHighVolt)
		{
			if (++msCntOvp >= strInput.OvpTimeMs)
			{
				strInput.ErrorFlag.bits.gHighVolt = 1;
			}
		}
	}
	else
	{
		if(msCntOvp > 0 )
		{
			msCntOvp--;
		}
		else
		{
			strInput.ErrorFlag.bits.gHighVolt = 0;
		}
		
	}
#endif		
}
/***********************************************************************************************************************
* Function Name:
* Description  : 
* Arguments    : 
* Return Value : 
***********************************************************************************************************************/

void UI_Get_Temperature(void)
{
	static uint16_t msCnt1Otp = 0;
	static uint16_t msCnt2Otp = 0;
/*
NTC1 MOS
*/

	strInput.OtpAdc1P = OTP_ADC1_P;
	strInput.OtpAdc1R = OTP_ADC1_R;

	strInput.OtpAdc2P = OTP_ADC2_P;
	strInput.OtpAdc2R = OTP_ADC2_R;
	
	if(strUctr.CtrFlag.bits.gFirstStart)
	{
		strInput.OtpTime1Ms = TIME_SOTP_MS;
		strInput.OtpTime2Ms = TIME_SOTP_MS;
	}
	else
	{
		strInput.OtpTime1Ms = TIME_OTP1_MS;		
		strInput.OtpTime2Ms = TIME_OTP2_MS;
	}

	strInput.ntc1Adc = ADC1_GetResult(RESULT_NTC1);	//


	if(!strInput.ErrorFlag.bits.gMosTempAbnormal)	
	{
		if(strInput.ntc1Adc <= strInput.OtpAdc1P)
		{
			if(msCnt1Otp < strInput.OtpTime1Ms)
			{
				msCnt1Otp++;
			}
			else
			{
				strInput.ErrorFlag.bits.gMosTempAbnormal = 1;
			}
		}	
		else
		{
			if(msCnt1Otp)
			{
				msCnt1Otp--;
			}
		}
	}
	else 
	{
		if(strInput.ntc1Adc > strInput.OtpAdc1R)
		{
			if (msCnt1Otp > 0)
			{
				msCnt1Otp--;
			}
			else
			{
				strInput.ErrorFlag.bits.gMosTempAbnormal= 0;
			}
		}
	}

/*
NTC2 PACK
*/
	strInput.ntc2Adc = ADC1_GetResult(RESULT_NTC2);	//

	if(!strInput.ErrorFlag.bits.gPackTempAbnormal)
	{
		if(strInput.ntc2Adc <= strInput.OtpAdc2P)
		{
			if(msCnt2Otp < strInput.OtpTime2Ms)
			{
				msCnt2Otp++;
			}
			else
			{
				strInput.ErrorFlag.bits.gPackTempAbnormal= 1;
			}
		}
		else
		{
			if (msCnt2Otp > 0)
			{
				msCnt2Otp --;
			}
		}
	}
	else 
	{
		if(strInput.ntc2Adc > strInput.OtpAdc2R)
		{
			if (msCnt2Otp > 0)
			{
				msCnt2Otp--;
			}
			else
			{
				strInput.ErrorFlag.bits.gPackTempAbnormal= 0;
			}
		}
	}	
}

/***********************************************************************************************************************
* Function Name:
* Description  : 
* Arguments    : 
* Return Value : 
***********************************************************************************************************************/
//uint32_t test1[300];
//uint32_t test2[300];
//uint16_t cnttest = 0;

uint32_t rpp_avrcur=0;
void UI_Get_Bus_Curt(void)
{
#if(OCP1_EN)
	static uint16_t msCntOcp1 = 0;
#endif
	
	static uint16_t msCntOcp2 = 0;
	static uint16_t msCntOcp3 = 0;
	static uint16_t msCntOcp4 = 0;

	static uint16_t msCntOpp1 = 0;

	uint16_t avg_curt_temp;
	uint16_t peak_curt_temp;

	
	strInput.busAvgCurrentAdc = strMcore.AvgCurtAdc;	    

	
	if( strInput.busAvgCurrentAdc > strMcore.AvgCurtOffSet )
	{
		avg_curt_temp = ( strInput.busAvgCurrentAdc - strMcore.AvgCurtOffSet);  //
	}
	else
	{
		avg_curt_temp = 0x0;
	}
	rpp_avrcur=avg_curt_temp;
	strInput.busAvgCurrentmA = Calculate_ADC_Ibus(avg_curt_temp);	

	/*
	if(++cnttest >= 300)
	{
		cnttest = 0;
	}
	test1[cnttest] = strInput.busAvgCurrentmA;
	test2[cnttest] =  strInput.busPeakCurrentAdc;
	*/

#if(1)	
/*ocp4*/	
	if (strInput.busAvgCurrentmA > strInput.OcpmA4)
	{
		if(msCntOcp4 < strInput.OcpTimeMs4)
		{
			msCntOcp4++;
		}
		else
		{
			strInput.ErrorFlag.bits.gOcp4 = 1;
		}
	}
	else
	{
		if(msCntOcp4)
		{
			msCntOcp4--;
		}
		strInput.ErrorFlag.bits.gOcp4 = 0;		
	}
/*ocp3*/
	if (strInput.busAvgCurrentmA > strInput.OcpmA3)
	{
		if(msCntOcp3 < strInput.OcpTimeMs3)
		{
			msCntOcp3++;
		}
		else
		{
			strInput.ErrorFlag.bits.gOcp3 = 1;
		}
	}
	else
	{		
		if(msCntOcp3)
		{
			msCntOcp3--;
		}
		strInput.ErrorFlag.bits.gOcp3 = 0;		
	}
/*ocp2*/
	if (strInput.busAvgCurrentmA > strInput.OcpmA2)
	{
		if(msCntOcp2 < strInput.OcpTimeMs2)
		{
			msCntOcp2++;
		}
		else
		{
			strInput.ErrorFlag.bits.gOcp2 = 1;
		}
	}
	else
	{
		if(msCntOcp2)
		{
			msCntOcp2--;
		}
		strInput.ErrorFlag.bits.gOcp2 = 0;		
	}
/*ocp1*/
	#if(OCP1_EN)
	if (strInput.busAvgCurrentmA > strInput.OcpmA1)
	{
		if(msCntOcp1 < strInput.OcpTimeMs1)
		{
			msCntOcp1++;
		}
		else
		{
			strInput.ErrorFlag.bits.gOcp1 = 1;
		}
	}
	else
	{
		if(msCntOcp1)
		{
			msCntOcp1--;
		}
		strInput.ErrorFlag.bits.gOcp1 = 0;		
	}
	#endif
	
#endif

#if(0)
/*ocp4*/	
	if (currentTemp > strInput.OcpADC4)
	{
		if(msCntOcp4 < strInput.OcpTimeMs4)
		{
			msCntOcp4++;
		}
		else
		{
			strInput.sensorFlag.bits.gOcp4 = 1;
		}
	}
	else
	{
		msCntOcp4 = 0;
		strInput.sensorFlag.bits.gOcp4 = 0;		
	}
/*ocp3*/
	if (currentTemp > strInput.OcpADC3)
	{
		if(msCntOcp3 < strInput.OcpTimeMs3)
		{
			msCntOcp3++;
		}
		else
		{
			strInput.sensorFlag.bits.gOcp3 = 1;
		}
	}
	else
	{		
		msCntOcp3 = 0;
		strInput.sensorFlag.bits.gOcp3 = 0;		
	}
/*ocp2*/
	if (currentTemp > strInput.OcpADC2)
	{
		if(msCntOcp2 < strInput.OcpTimeMs2)
		{
			msCntOcp2++;
		}
		else
		{
			strInput.sensorFlag.bits.gOcp2 = 1;
		}
	}
	else
	{
		msCntOcp2 = 0;
		strInput.sensorFlag.bits.gOcp2 = 0;		
	}
/*ocp1*/
	if (currentTemp > strInput.OcpADC1)
	{
		if(msCntOcp1 < strInput.OcpTimeMs1)
		{
			msCntOcp1++;
		}
		else
		{
			strInput.sensorFlag.bits.gOcp1 = 1;
		}
	}
	else
	{
		msCntOcp1 = 0;
		strInput.sensorFlag.bits.gOcp1 = 0;		
	}	

#endif	

	/*peak current protect*/
	strInput.busPeakCurrentAdc = strMcore.PeakCurtAdc;
	
	if( strInput.busPeakCurrentAdc > strMcore.PeakCurtOffset)
	{
		peak_curt_temp = ( strInput.busPeakCurrentAdc - strMcore.PeakCurtOffset);
	}
	else
	{
		peak_curt_temp = 0x0;
	}
	
	strInput.busPeakCurrentmA = Calculate_ADC_Ibus(peak_curt_temp);


	if (strInput.busPeakCurrentmA > strInput.OppmA1)
	{
		if(msCntOpp1 < strInput.OppTimeMs1)
		{
			msCntOpp1++;
		}
		else
		{
			strInput.ErrorFlag.bits.gOpp1 = 1;
		}
	}
	else
	{
		if(msCntOpp1)
		{
			msCntOpp1--;
		}
		strInput.ErrorFlag.bits.gOpp1 = 0;		
	}
}




/***********************************************************************************************************************
* Function Name:
* Description  : 
* Arguments    : 
* Return Value : 
***********************************************************************************************************************/

